// 两位数字，十位指的是端口号P0、P1、P2、P3
// 按键被按下，对应按键转换为数组下标
unsigned char key_ports[] = {
    0, 1, 2, 3,            // P00 P01 P02 P03
    10, 11, 12, 13, 14, 15 // P10 P11 P12 P13 P14 P15
};

#define KEY_COUNT (sizeof(key_ports) / sizeof(key_ports[0]))

typedef struct
{
    unsigned char port_num; // 对应的P0、P1、P2或P3
    unsigned char mask;     // 对应的引脚
} KeyConfig;

KeyConfig key_configs[KEY_COUNT];

void init_key_config()
{
    unsigned char i;
    for (i = 0; i < KEY_COUNT; i++)
    {
        key_configs[i].port_num = key_ports[i] / 10;
        key_configs[i].mask = 1 << (key_ports[i] % 10);
    }
}

#define GET_PORT_DATA(port_num) ((port_num == 0) ? P0 : (port_num == 1) ? P1 \
                                                    : (port_num == 2)   ? P2 \
                                                                        : P3)

unsigned char key_scan()
{
    unsigned char i;
    for (i = 0; i < KEY_COUNT; i++)
    {
        // GET_PORT_DATA(key_configs[i].port_num) 将数字0,1,2,3 转换为P0，P1，P2，P3
        if ((GET_PORT_DATA(key_configs[i].port_num) & key_configs[i].mask) == 0)
        {
            while ((GET_PORT_DATA(key_configs[i].port_num) & key_configs[i].mask) == 0)
            {
                // 等待按键释放
            }

            return i;
        }
    }
    return 0xFF;
}